﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using CardPlay.Model;
using CardPlay.Model.GameModel;
using CardPlay.Model.Primitives;

namespace CardPlay.DemoPack
{
    [Export(typeof(IGamePackage))]
    public class GamePackage : IGamePackage
    {
        public class GameInfo : IGameDescriptor
        {
            private readonly Type _type;
            private readonly GameAttribute _traits;

            public GameInfo(Type type, GameAttribute traits)
            {
                _type = type;
                _traits = traits;
            }

            public string DisplayName
            {
                get { return NameFromType(_type); }
            }

            ICardGame IGameDescriptor.CreateInstance()
            {
                return (ICardGame) Activator.CreateInstance(_type);
            }

            private static string NameFromType(Type type)
            {
                var name = Resources.ResourceManager.GetString("Title_" + type.Name);
                return !String.IsNullOrEmpty(name) ? name : type.Name.SplitIntoWords();
            }

            public Guid Id
            {
                get { return _traits.Id; }
            }

            public string Family
            {
                get { return _traits.Family; }
            }

            public int NumberOfDecks
            {
                get { return _traits.NumberOfDecks; }
            }

            public LevelOfSkill LevelOfSkill
            {
                get { return _traits.LevelOfSkill; }
            }

            public LevelOfDifficulty LevelOfDifficulty
            {
                get { return _traits.LevelOfDifficulty; }
            }

            public DurationOfPlay TypicalPlayingTime
            {
                get { return _traits.TypicalPlayingTime; }
            }

            public override string ToString()
            {
                return DisplayName;
            }
        }

        static GameInfo GameInfoFromType(Type type)
        {
            var traits = type.GetCustomAttributes(typeof(GameAttribute), false).OfType<GameAttribute>().FirstOrDefault();

            // ReSharper disable PossibleNullReferenceException
            return traits != null && type.IsClass && type.IsPublic && !type.IsAbstract && type.FullName.StartsWith("CardPlay.DemoPack.Games.")
                ? new GameInfo(type, traits)
                : null;
            // ReSharper restore PossibleNullReferenceException
        }

        IEnumerable<IGameDescriptor> IGamePackage.Games
        {
            get 
            { 
                return Assembly.GetExecutingAssembly().GetTypes()
                    .Select(GameInfoFromType)
                    .Where(i => i != null); 
            }
        }
    }
}
